home *** CD-ROM | disk | FTP | other *** search
/ Aminet 51 / Aminet 51 (2002)(GTI - Schatztruhe)[!][Oct 2002].iso / Aminet / util / arc / xadmasterdev.lha / xad / Sources / clients / PackDev.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-08-20  |  8.7 KB  |  316 lines

  1. #ifndef XADMASTER_PACKDEV_C
  2. #define XADMASTER_PACKDEV_C
  3.  
  4. /* Programmheader
  5.  
  6.     Name:        PackDev.c
  7.     Main:        xadmaster
  8.     Versionstring:    $VER: PackDev.c 1.5 (20.01.2001)
  9.     Author:        SDI
  10.     Distribution:    Freeware
  11.     Description:    PackDev disk archiver client
  12.  
  13.  1.0   13.06.98 : first version
  14.  1.1   13.02.99 : started again with that client
  15.  1.2   20.06.99 : removed exec.library calls
  16.  1.3   29.06.99 : now uses master free stuff
  17.  1.4   29.08.99 : now uses xdi_DataPos
  18.  1.5   20.01.01 : fixed bug with Block-Field and Boot-Blocks
  19. */
  20.  
  21. /* For now SectorLabel information is ignored, as current
  22. PackDev has empty labels always. */
  23.  
  24. #include <proto/xadmaster.h>
  25. #include <devices/trackdisk.h>
  26. #include "SDI_compiler.h"
  27. #define SDI_TO_ANSI
  28. #include "SDI_ASM_STD_protos.h"
  29. #include "xadXPK.c"
  30. #include "ConvertE.c"
  31.  
  32. #ifndef XADMASTERFILE
  33. #define PackDev_Client        FirstClient
  34. #define NEXTCLIENT        0
  35. #define XADMASTERVERSION    8
  36. UBYTE version[] = "$VER: PackDev 1.4 (29.08.1999)";
  37. #endif
  38. #define PACKDEV_VERSION        1
  39. #define PACKDEV_REVISION    4
  40.  
  41. struct PackDevHead {
  42.   UBYTE        pd_Header[4];    /* equals 'PKD\x13' */
  43.   ULONG        pd_BlockNum;    /* Number of blocks */
  44.   ULONG        pd_BlockSize;    /* size of one block */
  45.   ULONG        pd_Reserved;    /* Reserved blocks */
  46.   ULONG        pd_TrackLength;    /* Length of one track*/
  47.   ULONG        pd_xpkBufferSize; /* in byte */
  48.   ULONG        pd_xpkPacker;    /* XPK packer type */
  49.   ULONG pad1;    /* These are fields containing the XPK packer name */
  50.   ULONG pad2;    /* Don't know, why the author used 24bytes instead */
  51.   ULONG pad3;    /* of the required 4. */
  52.   ULONG pad4;    /* The fields are ignored by that client */
  53.   ULONG pad5;
  54.   UWORD        pd_xpkMode;     /* XPK mode Number 0..100 */
  55.   UWORD        pd_KnownFileSys; /* When all data stored, this is 0, else 1 */
  56. };
  57.  
  58. struct PackDevHeadOld {
  59.   UBYTE        pd_Header[4];    /* equals 'PKD\x11' */
  60.   ULONG        pd_BlockNum;    /* Number of blocks */
  61.   ULONG        pd_BlockSize;    /* size of one block */
  62.   ULONG        pd_Reserved;    /* Reserved blocks */
  63.   ULONG        pd_TrackLength;    /* Length of one track*/
  64.   ULONG        pd_xpkBufferSize; /* in byte */
  65.   ULONG        pd_xpkPacker;    /* XPK packer type */
  66.   UWORD        pd_xpkMode;     /* XPK mode Number 0..100 */
  67.   UWORD        pd_KnownFileSys; /* When all data stored, this is 0, else 1 */
  68. };
  69.  
  70. /* Every block has following structure:
  71.  ULONG size
  72.  ULONG data[...]
  73.  ULONG checksum
  74.  
  75. Where data are the blocks and additionally the SectorLabels (16 Byte).
  76.  
  77. Checksum is missing in PackDev11 Version.
  78. */
  79.  
  80. #define PKD_XPKPACKED    (1<<0)
  81. #define PKD_OLDMODE    (1<<1)
  82.  
  83. ASM(BOOL) PackDev_RecogData(REG(d0, ULONG size), REG(a0, STRPTR data),
  84. REG(a6, struct xadMasterBase *xadMasterBase))
  85. {
  86.   if(((ULONG *)data)[0] == 0x504B4413 || ((ULONG *)data)[0] == 0x504B4411)
  87.     return 1;
  88.   else
  89.     return 0;
  90. }
  91.  
  92. static LONG PKDdecrBuf(STRPTR *buf, ULONG *i, struct xadArchiveInfo *ai,
  93. struct xadMasterBase *xadMasterBase, ULONG oldmode)
  94. {
  95.   LONG err, size;
  96.   if(!(err = xadHookAccess(XADAC_READ, 4, &size, ai)))
  97.   {
  98.     if(!(err = xpkDecrunch(buf, i, ai, xadMasterBase)))
  99.     {
  100.       if(!oldmode)
  101.         err = xadHookAccess(XADAC_READ, 4, &size, ai);
  102.     }
  103.   }
  104.   return err;
  105. }
  106.  
  107. /* maybe there are some errors in that code, not tested yet */
  108. ASM(LONG) PackDev_GetInfo(REG(a0, struct xadArchiveInfo *ai),
  109. REG(a6, struct xadMasterBase *xadMasterBase))
  110. {
  111.   struct PackDevHead h;
  112.   LONG err;
  113.  
  114.   if(!(err = xadHookAccess(XADAC_READ, sizeof(struct PackDevHeadOld), &h, ai)))
  115.   {
  116.     if(h.pd_Header[3] == 0x11 || !(err = xadHookAccess(XADAC_READ,
  117.     sizeof(struct PackDevHead)-sizeof(struct PackDevHeadOld), ((STRPTR) &h) +
  118.     sizeof(struct PackDevHeadOld), ai)))
  119.     {
  120.       struct xadDiskInfo *xdi;
  121.       ULONG blksiz = 0, i, dat[10], spos;
  122.       STRPTR buf = 0;
  123.  
  124.       if(h.pd_Header[3] == 0x11)
  125.       {
  126.         h.pd_KnownFileSys = ((struct PackDevHeadOld *) &h)->pd_KnownFileSys;
  127. /*      h.pd_xpkMode = ((struct PackDevHeadOld *) &h)->pd_xpkMode; */
  128.       }
  129.     
  130.       /* check for password flag */
  131.       if(h.pd_xpkPacker && !err && !(err = xadHookAccess(XADAC_READ, 40, dat, ai))
  132.       && !(err = xadHookAccess(XADAC_INPUTSEEK, -40, 0, ai)))
  133.       {
  134.         if(dat[9] & (1<<25))
  135.           ai->xai_Flags |= XADAIF_CRYPTED;
  136.       }
  137.  
  138.       spos = ai->xai_InPos;
  139.       
  140.       if(h.pd_KnownFileSys)
  141.       {
  142.         blksiz = h.pd_BlockNum;
  143.         if(h.pd_xpkPacker)
  144.           err = PKDdecrBuf(&buf, &i, ai, xadMasterBase, h.pd_Header[3] == 0x11);
  145.         else
  146.         {
  147.           if(!(buf = (STRPTR) xadAllocVec((i = blksiz>>3), MEMF_ANY)))
  148.             err = XADERR_NOMEMORY;
  149.           else
  150.           {
  151.             err = xadHookAccess(XADAC_READ, i, buf, ai);
  152.             spos = ai->xai_InPos;
  153.           }
  154.         }
  155.       }
  156.     
  157.       if(!err)
  158.       {
  159.         if((xdi = (struct xadDiskInfo *) xadAllocObject(XADOBJ_DISKINFO,
  160.         blksiz ? XAD_OBJBLOCKENTRIES : TAG_DONE, blksiz, TAG_DONE)))
  161.         {
  162.           if(ai->xai_Flags & XADAIF_CRYPTED)
  163.             xdi->xdi_Flags |= XADDIF_CRYPTED;
  164.           xdi->xdi_Flags |= XADDIF_NOCYLINDERS|XADDIF_NOLOWCYL|XADDIF_SEEKDATAPOS|
  165.                         XADDIF_NOHIGHCYL|XADDIF_NOHEADS|XADDIF_NOCYLSECTORS;
  166.           xdi->xdi_TotalSectors = h.pd_BlockNum;
  167.           xdi->xdi_SectorSize = h.pd_BlockSize;
  168.           xdi->xdi_TrackSectors = h.pd_TrackLength / h.pd_BlockSize;
  169.           xdi->xdi_EntryNumber = 1;
  170.           xdi->xdi_DataPos = spos;
  171.           i = 0;
  172.           if(h.pd_xpkPacker)
  173.             i |= PKD_XPKPACKED;
  174.           if(h.pd_Header[3] == 0x11)
  175.             i |= PKD_OLDMODE;
  176.           xdi->xdi_PrivateInfo = (APTR) i;
  177.           ai->xai_DiskInfo = xdi;
  178.  
  179.       /* does nothing if blksiz == 0 */
  180.       if(blksiz)
  181.       {
  182.         blksiz -= h.pd_Reserved;
  183.         for(i = 0; i < blksiz;)
  184.             {
  185.               ULONG l, j;
  186.  
  187.               l = EndGetM32(buf+(i>>3));
  188.               for(j = 0; j < 32; ++j)
  189.               {
  190.                 if(l & (1 << j))
  191.                   xdi->xdi_BlockInfo[i+h.pd_Reserved] |= XADBIF_CLEARED;
  192.                 ++i;
  193.               }
  194.             }
  195.           }
  196.         }
  197.         else
  198.           err = XADERR_NOMEMORY;
  199.       }
  200.       if(buf)
  201.         xadFreeObjectA(buf, 0);
  202.     }
  203.   }
  204.  
  205.   return err;
  206. }
  207.  
  208. ASM(LONG) PackDev_UnArchive(REG(a0, struct xadArchiveInfo *ai),
  209. REG(a6, struct xadMasterBase *xadMasterBase))
  210. {
  211.   ULONG i, j, trsec, numsecs = 0;
  212.   LONG err = 0, secsize;
  213.   struct xadDiskInfo *di;
  214.   STRPTR temp;
  215.   
  216.   di = ai->xai_CurDisk;
  217.   secsize = di->xdi_SectorSize;
  218.   trsec = di->xdi_TrackSectors;
  219.  
  220.   if(!(temp = xadAllocVec(di->xdi_SectorSize*di->xdi_TrackSectors, MEMF_ANY)))
  221.     return XADERR_NOMEMORY;
  222.  
  223.   if(!(((ULONG) di->xdi_PrivateInfo) & PKD_XPKPACKED))
  224.   {
  225.     numsecs = 0;
  226.     for(i = 0; !err && i < di->xdi_TotalSectors; ++i)
  227.     {
  228.       j = (i % trsec)*secsize;
  229.     
  230.       if(di->xdi_BlockInfo && di->xdi_BlockInfo[i])
  231.         memset(temp+j, 0, secsize);
  232.       else
  233.       {
  234.         err = xadHookAccess(XADAC_READ, secsize, temp+j, ai);
  235.         ++numsecs;
  236.       }
  237.       /* skip the empty sectorlabels and write data */
  238.       if((i % trsec) == (trsec-1) && !err)
  239.       {
  240.         if(!numsecs || !(err = xadHookAccess(XADAC_INPUTSEEK, TD_LABELSIZE*numsecs, 0, ai)))
  241.           err = xadHookAccess(XADAC_WRITE, trsec*secsize, temp, ai);
  242.         numsecs = 0;
  243.       }
  244.     }
  245.   }
  246.   else
  247.   {
  248.     ULONG size;
  249.     LONG pos = 0, ressize;
  250.     STRPTR buf = 0;
  251.  
  252.     err = PKDdecrBuf(&buf, &size, ai, xadMasterBase,
  253.     (((ULONG) di->xdi_PrivateInfo) & PKD_OLDMODE));
  254.  
  255.     if(di->xdi_BlockInfo)
  256.       pos += di->xdi_TotalSectors>>3;
  257.  
  258.     for(i = 0; !err && i < di->xdi_TotalSectors; ++i)
  259.     {
  260.       j = (i % trsec)*secsize;
  261.       
  262.       if(di->xdi_BlockInfo && di->xdi_BlockInfo[i])
  263.         memset(temp+j, 0, secsize);
  264.       else
  265.       {
  266.         ++numsecs;
  267.         if((ressize = size-pos) >= secsize)
  268.         {
  269.           xadCopyMem(buf+pos, temp+j, secsize);
  270.           pos += secsize;
  271.         }
  272.         else
  273.         {
  274.           if(ressize > 0)
  275.           {
  276.             xadCopyMem(buf+pos, temp+j, ressize);
  277.             pos += ressize;
  278.           }
  279.           else if(ressize < 0)
  280.             ressize = 0;
  281.           xadFreeObjectA(buf, 0);
  282.           buf = 0;
  283.           pos -= size;
  284.           if(!(err = PKDdecrBuf(&buf, &size, ai, xadMasterBase,
  285.           (((ULONG) di->xdi_PrivateInfo) & PKD_OLDMODE))))
  286.           {
  287.             xadCopyMem(buf+pos, temp+j+ressize, secsize-ressize);
  288.             pos += secsize-ressize;
  289.           }
  290.         }
  291.       }
  292.       /* skip the empty sectorlabels and write data */
  293.       if((i % trsec) == (trsec-1) && !err)
  294.       {
  295.         pos += TD_LABELSIZE*numsecs;
  296.         err = xadHookAccess(XADAC_WRITE, trsec*secsize, temp, ai);
  297.         numsecs = 0;
  298.       }
  299.     }
  300.     if(buf)
  301.       xadFreeObjectA(buf, 0);
  302.   }
  303.  
  304.   xadFreeObjectA(temp, 0);
  305.  
  306.   return err;
  307. }
  308.  
  309. const struct xadClient PackDev_Client = {
  310. NEXTCLIENT, XADCLIENT_VERSION, XADMASTERVERSION, PACKDEV_VERSION, PACKDEV_REVISION,
  311. 4, XADCF_DISKARCHIVER|XADCF_FREEDISKINFO, XADCID_PACKDEV, "PackDev",
  312. (BOOL (*)()) PackDev_RecogData, (LONG (*)()) PackDev_GetInfo,
  313. (LONG (*)()) PackDev_UnArchive, 0};
  314.  
  315. #endif /* XADMASTER_PACKDEV_C */
  316.